package com.sql.parse;

import com.google.common.collect.Lists;
import com.sql.parse.ognl.*;
import org.apache.commons.io.IOUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import com.sql.parse.common.Constants;
import com.sql.parse.parsing.XNode;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;


 class SqlParseProcess implements IParse {
    private static final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();


    @Override
    public String parseText(String text, Map<String, Object> paramMap) {

        if (text == null || text.trim().length() == 0) {
            throw new IllegalArgumentException("text is null ");
        }
        PlaceHolder placeHolder = new PlaceHolder();
        placeHolder.setPrefix("#{");
        placeHolder.setSuffix("}");
        return parseText(text,paramMap, Lists.newArrayList(placeHolder));
    }

    @Override
    public String parseText(String text, Map<String, Object> paramMap, Collection<PlaceHolder> placeHolders) {
        if (text == null || text.trim().length() == 0) {
            throw new IllegalArgumentException("text is null ");
        }
        for (PlaceHolder placeHolder : placeHolders) {
            if (placeHolder.getPrefix() == null || placeHolder.getSuffix() == null) {
                throw new IllegalArgumentException("placeholder is null");
            }
        }
        XNode xNode = generateNode(text);
        List<DataNode> sqlNodes = new ParseSql(placeHolders).parseDynamicTags(xNode);
        MixedSqlNode rootSqlNode = new MixedSqlNode(sqlNodes);
        MySqlSource sqlSource = new MyDynamicSqlSource(rootSqlNode, placeHolders);
        MyDynamicContext myDynamicContext = sqlSource.getSqlContext(paramMap);
        return myDynamicContext.getSql();
    }

    private XNode generateNode(String text) {
        InputStream inputStream = null;
        try {
            String sqlTemp = getDomTemplate(text);
            inputStream = new ByteArrayInputStream(sqlTemp.getBytes("UTF-8"));
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(inputStream);
            Node node = doc.getChildNodes().item(0);
            XNode xNode = new XNode(null, node, null);
            return xNode;
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
    }

    private String getDomTemplate(String sql) {
        StringBuilder stringBuilder = new StringBuilder(Constants.SELECT_START_LABEL);
        stringBuilder.append(sql);
        stringBuilder.append(Constants.SELECT_END_LABEL);
        return stringBuilder.toString();
    }
}
